package com.yerbamateprimer.advice.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.google.common.base.Preconditions;
import com.yerbamateprimer.advice.SingleReceptorAdvice;
import com.yerbamateprimer.model.Group;
import com.yerbamateprimer.model.User;

/**
 * This class models an advice
 * to let the primer know that  
 * could invite groups of users 
 * to the round.
 * 
 * @author Matias Liwski
 * @version 1.0
 */
public class InviteUsersAdvice implements SingleReceptorAdvice {
	private static final long serialVersionUID = 5922377151554905620L;
	private User receptor;
	private Set<Group> groupsToInvite;

	/**
	 * @param receptor The receptor of this advice.
	 * @param groupsToInvite The groups of users that the receptor could invite.
	 */
	public InviteUsersAdvice(User receptor, Collection<Group> groupsToInvite) {
		this.groupsToInvite = new HashSet<Group>();
		setAdviceReceptor(receptor);
		addAllGroupsToInvite(groupsToInvite);
	}

	/* (non-Javadoc)
	 * @see com.yerbamateprimer.advice.SingleReceptorAdvice#setReceptor(com.yerbamateprimer.model.User)
	 */
	@Override
	public void setAdviceReceptor(User adviceReceptor) {
		Preconditions.checkArgument(adviceReceptor != null, "This advice need a receptor.");
		this.receptor = adviceReceptor;
	}

	/* (non-Javadoc)
	 * @see com.yerbamateprimer.advice.SingleReceptorAdvice#getReceptor()
	 */
	@Override
	public User getAdviceReceptor() {
		return this.receptor;
	}

	/**
	 * @param group A group to add to the invited groups list.
	 */
	public void addGroupToInvite(Group group){
		Preconditions.checkArgument(group != null, "Couldn't invite a null group to a round.");
		this.groupsToInvite.add(group);
	}

	/**
	 * @param groups Several groups to add to the invited groups list.
	 */
	public void addAllGroupsToInvite(Collection<Group> groups){
		Preconditions.checkArgument(groups != null && !groups.isEmpty(), "This advice needs groups to invite (groups=" + groups + ").");
		this.groupsToInvite.addAll(groups);
	}

	/**
	 * @return A safe copy of the users group list to invite.
	 */
	public Collection<Group> getGroupsToInvite(){
		return new ArrayList<Group>(this.groupsToInvite);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE, false, false);
	}
}